package com.socket.server.request;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * 语音识别相关功能
 */
@Slf4j
@Component
public class SpeechRequest {
    private static final String OAUTH_2 = "https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id=ObTPO56aMGDTP0Ttj9VjUk6a&client_secret=pIkvZf08xqi86ImHNgO14ir9nLpRLGqh";
    private static final String CONVERT_URL = "https://vop.baidu.com/server_api";

    /**
     * 音频文件转换文本
     *
     * @param bytes 文件数据
     * @return 文本
     */
    public String convertText(byte[] bytes) {
        JSONObject json = new JSONObject();
        json.set("cuid", "webchat");
        json.set("format", "wav");
        json.set("rate", "16000");
        json.set("channel", 1);
        json.set("token", getAccessToken());
        json.set("speech", Base64.encode(bytes));
        json.set("len", bytes.length);
        String body = HttpRequest.post(CONVERT_URL).body(json.toString()).execute().body();
        try {
            return JSONUtil.parseObj(body).getJSONArray("result").getStr(0);
        } catch (Exception e) {
            log.info("语音转换文字错误：{}", e.getMessage());
            return null;
        }
    }

    /**
     * 获得AccessToken
     */
    private String getAccessToken() {
        String body = HttpRequest.get(OAUTH_2).execute().body();
        return JSONUtil.parseObj(body).getStr("access_token");
    }

    public String assembleAuthUrl(String hosturl, String apiKey, String apiSecret) {
        // Parse the host url
        URL ul = URLUtil.getURL(hosturl);
        // Get the current date in UTC format
        String date = DateUtil.formatHttpDate(DateUtil.date());
        // The fields to be signed: host, date, request-line
        String[] arr = new String[]{"host: " + ul.getHost(), "date: " + date, "GET " + ul.getPath() + " HTTP/1.1"};
        // Join the sign string with newline
        String sign = StrUtil.join("\n", arr);
        // Compute the signature with hmac-sha256 and base64 encoding
        String sha = SecureUtil.hmacSha256(apiSecret).digestBase64(sign, false);
        // Build the request parameters without url encoding
        String authUrl = StrUtil.format("api_key=\"{}\", algorithm=\"{}\", headers=\"{}\", signature=\"{}\"", apiKey,
                "hmac-sha256", "host date request-line", sha);
        // Encode the request parameters with base64
        String authorization = Base64.encode(authUrl);
        // Create a query string with url encoding
        Map<String, Object> params = MapUtil.newHashMap();
        params.put("host", ul.getHost());
        params.put("date", date);
        params.put("authorization", authorization);
        String query = URLUtil.buildQuery(params, StandardCharsets.UTF_8);
        // Concatenate the url and the query string
        return StrUtil.concat(false, ul.toString(), "?", query);
    }
}
